//+------------------------------------------------------------------+
//|    V O S T O K  [Alpha 1] by Nicolas S. (aka Nykoes) 
//|                   www.forexagone.com 
//|                        June 2011
//+------------------------------------------------------------------+

#property copyright "Nykoes (June 2011)"
#define NAME "VOSTOK-internal"
#define VERSION "alpha 1"

int MAGICNUMBER = 181818;
int MAGICNUMMAX = 181819;
extern double Lots = 0.1;

extern int MaxTradingAllCharts = 6;
extern int MaxTradingThisPair = 1;
extern int AccountSecurity = 500;

extern int AccountObjective = 2000;
extern bool EnableDailyPairObjective = false;
extern double DailyPairObjective = 100;
bool StopDayProfit = false;

double MaximumRisk = 0.036;
double DecreaseFactor = -12;
extern int digit = 0;
double TakeProfit = 50;
extern double StopLoss = 50;
double MAPeriod = 1.0;

bool openSound = false;
bool closeSound = false;
extern int StartHour = 0;
//extern int StartMinute = 0;
extern int StopHour = 23;
//extern int StopMinute = 59;
bool NoTradingTime = true;
int i;
string symbolpair;
int CountedOrders = 0;
int PairDigit=0;
double point;
int TREND = 0;
      int STOCH;
      int ADX;
      int TRENDplus;
      int MI;
      int LRI15,LRI30;
int TimeDifference=0;
double profit = 0;

extern bool EnableTrailing = false;
extern int trendTrigger = 3;
extern int trendStoploss = 5;

extern string LabelTimeOut = "***Orders Time Out*** // DONT USE IT (BETA DEV)"; 
extern bool EnableOrdersTimeOut = false; // Don't use it, early development !
extern double ProfitTimeOutFactor = 0.8;
extern double LossTimeOutFactor = 0.8;

extern string LabelMaxiProfit = "***Maximize Profit***"; 
extern bool EnableMaximizeProfit = true; // Don't use it, early development !
extern double MaximizeProfitTreshold = 15;
extern double StopLossMaximize = 20; 

//external variable for TSSF
extern bool TssfActivated = true;
extern int LastXTrades=10; 
extern int ProportionalRisk=90; 
extern double TSSFTrigger1=1; 
extern int TSSFRatio1=50; 
extern double TSSFTrigger2=2; 
extern int TSSFRatio2=75; 
extern double TSSFTrigger3=3; 
extern int TSSFRatio3=100;
//tssf variable
int orders; 
int tradegagnant,tradeperdant; 
double profit2, perte, avgwin, avgloss, prcwin, tssf;
double MyPoint;


//+------------------------------------------------------------------+
//| expert initialization function |
//+------------------------------------------------------------------+
int init() {
    MyPoint=Point * MathPow(10, Digits % 2);
    return(0);
}
//+------------------------------------------------------------------+
//| expert deinitialization function |
//+------------------------------------------------------------------+
int deinit() {
    //----
    return(0);
}
//+------------------------------------------------------------------+
//| expert start function |
//+------------------------------------------------------------------+
int start() {
   double Alpha;
   double MA, MAprevious;
   double Laguerre;
   

   int cnt, ticket, total;
   Alpha = iCCI(NULL, 0, 5, PRICE_MEDIAN, 1);
   
   if(iMA(NULL,0, 34, 0, MODE_EMA, PRICE_MEDIAN, 0)>iMA(NULL, 0, 34, 0, MODE_EMA, PRICE_MEDIAN, 1)) TREND = 1;
   if(iMA(NULL,0, 34, 0, MODE_EMA, PRICE_MEDIAN, 0)<iMA(NULL, 0, 34, 0, MODE_EMA, PRICE_MEDIAN, 1)) TREND = 0;

   symbolpair = Symbol();
   total = OrdersTotal();

   if(iMA(NULL,0, 10, 0, MODE_LWMA, PRICE_CLOSE, 0)>iMA(NULL, 0, 10, 0, MODE_LWMA, PRICE_CLOSE, 1)) TRENDplus = 1;
   if(iMA(NULL,0, 10, 0, MODE_LWMA, PRICE_CLOSE, 0)<iMA(NULL, 0, 10, 0, MODE_LWMA, PRICE_CLOSE, 1)) TRENDplus = 0;

   if(iStochastic(NULL,0,5,3,3,MODE_LWMA,1,MODE_MAIN,0)<= 20) STOCH = 1;
   if(iStochastic(NULL,0,5,3,3,MODE_LWMA,1,MODE_MAIN,0)>= 80) STOCH = 0;



   double UpperThresholdSTOCH = 80.0; //Upper stochastic value for alert
   double LowerThresholdSTOCH = 20.0; //Lower stochastic value for alert
   double stoch[2];

   bool CLOSEshortSTOCH;
   bool CLOSElongSTOCH;

   stoch[0] = iStochastic(NULL,0,5,3,3,MODE_LWMA,1,MODE_MAIN,0);
   stoch[1] = iStochastic(NULL,0,5,3,3,MODE_LWMA,1,MODE_MAIN,1);

    if ((stoch[0] <= UpperThresholdSTOCH) && (stoch[1] >= UpperThresholdSTOCH)) CLOSElongSTOCH=true;
    if ((stoch[0] >= LowerThresholdSTOCH) && (stoch[1] <= LowerThresholdSTOCH)) CLOSEshortSTOCH=true;      

   // *********
   //Objective reached ? 
   if(AccountBalance() > AccountObjective) {
   Print("No more trades, objective reached !");
   return(0);
   }
   // *********
   //Trades hours     
   if(TimeHour(TimeCurrent()) > StartHour && TimeHour(TimeCurrent()) < StopHour) { 
   //Print("Trade allowed on this time period ! : " + TimeHour(TimeCurrent()));
      NoTradingTime = false;
   }
   // *********
   //Orders count
   int scnt = 0, bcnt = 0, compteur = OrdersTotal();
       for (i = 0; i < compteur; i++) {
         OrderSelect(i, SELECT_BY_POS, MODE_TRADES); 
           if (OrderMagicNumber() == MAGICNUMBER || MAGICNUMMAX) {
             if (OrderType() == OP_BUY && OrderSymbol() == symbolpair)
             bcnt++; 
             else 
             if (OrderType() == OP_SELL && OrderSymbol() == symbolpair) 
             scnt++; 
            }
            }
   CountedOrders = bcnt + scnt;

   if (EnableTrailing) TrailStops(); //Go TrailingStop 

   if (EnableOrdersTimeOut) OrdersTimeOut(); // GO OrdersTimeOut

   if (EnableDailyPairObjective) DailyProfit(); //Go DailyProfit

   if (EnableMaximizeProfit) MaximizeProfit(); // Go MaximizeProfit


    if((total < MaxTradingAllCharts) && (CountedOrders < MaxTradingThisPair) && (NoTradingTime == false) && (StopDayProfit==false)) {  
        
        if(AccountFreeMargin() < ((AccountSecurity *10)*Lots)) { 
            return(0);
        }
        //Sleep(10000);
        // check for long position (BUY) possibility
        if((TREND==1) && (STOCH==1) && (Alpha < -100)) {
            ticket = OrderSend(Symbol(), OP_BUY, LotsOptimized(), Ask, 3, Ask - StopLoss * Point * MathPow(10, Digits % 2),
            0, NAME, MAGICNUMBER, 0, Green);
            Print(" TREND:",TREND," STOCH:",STOCH);
            if (GetLastError() == 0)
              openSound=true;
              
        }
        // check for short position (SELL) possibility
        if((TREND==0) && (STOCH==0) && (Alpha > 100)) { 
            ticket = OrderSend(Symbol(), OP_SELL, LotsOptimized(), Bid, 3, Bid + StopLoss * Point * MathPow(10, Digits % 2),
            0, NAME, MAGICNUMBER, 0, Red);
            Print(ADX," TREND:",TREND," STOCH:",STOCH);
            if (GetLastError() == 0)
              openSound=true;
        }
    }
    // Orders exit
    for (cnt = 0; cnt < total; cnt++) {
        OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
        if(OrderType() <= OP_SELL && // check for opened position
        OrderSymbol() == Symbol()) { // check for symbol 
            if(OrderType() == OP_BUY) { // long position is opened 
                // should it be closed?
                // check for stop
                if ((CLOSElongSTOCH==true)  ) {
                        OrderClose(OrderTicket(), OrderLots(), Bid, 3, Violet);
                          closeSound=true;
                        // close position
                        return(0);
                   // }
                }
            } // go to short position 
                // check for TakeProfit
                 if(OrderType() == OP_SELL) {
                if ((CLOSEshortSTOCH==true) ) { 
                        OrderClose(OrderTicket(), OrderLots(), Ask, 3, Violet);
                        ///----
                        // close position
                        return(0);
                    //}
                }
            }
        }
    }
    if (openSound) {
      PlaySound("alert2.wav");
      openSound = false;
    }
    if (closeSound) {
      PlaySound("expert.wav");
      closeSound = false;
    }
   
    return(0);
}
//+------------------------------------------------------------------+
//| Calculate optimal lot size |
//+------------------------------------------------------------------+
double LotsOptimized() {
    double lot = Lots;
    // was double lot = Lots;
    if(TssfActivated==false)
    {
      int orders = HistoryTotal();
      // history orders total
      int losses = 2;
      // number of losses orders without a break was 0 then 3
      //---- select lot size
      lot = NormalizeDouble(AccountFreeMargin()*MaximumRisk / 500, 1);
      //---- calcuulate number of losses orders without a break
      if(DecreaseFactor > 1) { 
          for (int i = orders - 1; i >= 0; i--) {
              if(OrderSelect(i, SELECT_BY_POS, MODE_HISTORY) == false) {
                  Print("Error in history!");
                  break;
              }
              //----
              if(OrderSymbol() != Symbol() || OrderType() > OP_SELL)
              continue;
              //----
              if(OrderProfit() > 0)
              break;
              //----
              if(OrderProfit() < 0)
              losses++;
          }
          if(losses > 1)
            lot = NormalizeDouble(lot - lot*losses / DecreaseFactor,1);
      }

      // was lot = 0.1;
    }
    else
    {
      orders=HistoryTotal();
      tradegagnant=0;
      tradeperdant=0;
      profit2=0;
      perte=0;
      avgwin=0;
      avgloss=0;
      prcwin=0;
      tssf=0;
      for(int j=orders-1;j>=orders-LastXTrades;j--)
      {
         if(OrderSelect(j,SELECT_BY_POS,MODE_HISTORY)==False) 
         { 
            Print("Erreur dans l historique!"); 
            break; 
         }

         if(OrderProfit()>=0)
         {
            tradegagnant++;
            profit2=profit2+OrderProfit();
         }
         else
         {
            tradeperdant++;
            perte=perte+OrderProfit();
         }


      }
      if (orders>LastXTrades)
      {
         avgwin=profit2/tradegagnant;
         avgloss=perte/tradeperdant;
         prcwin=tradegagnant/(tradegagnant+tradeperdant);
         tssf=avgwin/avgloss*((1.1-prcwin)/(prcwin-0.1)+1);
      }

      if(tssf<=TSSFTrigger1)lot=0.1;
      if(tssf>TSSFTrigger1&&tssf<=TSSFTrigger2)lot=NormalizeDouble(AccountFreeMargin()*ProportionalRisk/TSSFRatio1*100/100000,1);
      if(tssf>TSSFTrigger2&&tssf<=TSSFTrigger3)lot=NormalizeDouble(AccountFreeMargin()*ProportionalRisk/TSSFRatio2*100/100000,1);
      if(tssf>TSSFTrigger3)lot=NormalizeDouble(AccountFreeMargin()*ProportionalRisk/TSSFRatio3*100/100000,1);
    
    }
    //---- return lot size
    if(lot <0.1)// was if(lot < 0.1)
      lot = 0.1;
    return(lot);
}

//+------------------------------------------------------------------+
//| OrdersTimeOut (please don't use it : experimental)
//+------------------------------------------------------------------+
void OrdersTimeOut()
{

for (int cnt=0;cnt<OrdersTotal();cnt++)
    { 
     OrderSelect(cnt, SELECT_BY_POS);  
         if ( OrderSymbol()==Symbol() ) 
         {
         TimeDifference = (TimeCurrent() - OrderOpenTime());
         Print("timedifference = ", TimeDifference);
         if ((TimeDifference > 20000) && (OrderProfit() >= (TakeProfit * ProfitTimeOutFactor))) {
          if(OrderType() == OP_BUY) OrderClose(OrderTicket(), OrderLots(), Bid, 3, Violet); 
          if(OrderType() == OP_SELL) OrderClose(OrderTicket(), OrderLots(), Ask, 3, Violet);   
            }
         if ((TimeDifference > 20000) && (OrderProfit() >= (StopLoss * LossTimeOutFactor)) && (OrderProfit() < 0)) {
          if(OrderType() == OP_BUY) OrderClose(OrderTicket(), OrderLots(), Bid, 3, Violet); 
          if(OrderType() == OP_SELL) OrderClose(OrderTicket(), OrderLots(), Ask, 3, Violet);   
            }
     
}
}      
}

//+------------------------------------------------------------------+
//| DailyProfit management
//+------------------------------------------------------------------+
void DailyProfit()
{
  double profit = 0;
 
  int cnt = OrdersHistoryTotal();
  for (int i=0; i < cnt; i++) {
    if (!OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) continue;
    if (OrderSymbol()==Symbol()) continue;  
    if (TimeDayOfYear(OrderCloseTime()) == DayOfYear() && TimeYear(OrderCloseTime()) == Year()) profit += OrderProfit();
  }
 
  //return (profit);
if(profit > DailyPairObjective){
StopDayProfit = true; 
Print("Daily profit reached for this pair !");
}
}

//+------------------------------------------------------------------+
//| Maximize profit management
//+------------------------------------------------------------------+
void MaximizeProfit()
{

   bool AllowMaximize=true;

   int last_trade=OrdersHistoryTotal();
   if(last_trade>0)
   {
     if(OrderSelect(last_trade-1,SELECT_BY_POS,MODE_HISTORY)==true)
     {
         if(OrderSymbol()==Symbol() && OrderProfit()<0 && OrderMagicNumber()==MAGICNUMMAX) AllowMaximize = false;                
     }
   }


int scnt = 0, bcnt = 0, compteur = OrdersTotal();
    for (i = 0; i < compteur; i++) {
      //Sleep(1000);
      OrderSelect(i, SELECT_BY_POS, MODE_TRADES); 
        if ((OrderType() == OP_BUY) && (OrderSymbol() == symbolpair) && (OrderMagicNumber()==MAGICNUMBER || !MAGICNUMMAX) && (AllowMaximize == true) && (MI==1)) { //&& OrdersMaximizeLostToday==0 ) {//&& (TRENDplus==1)) { //&& TREND==1)  {
          if ((OrderSymbol() == symbolpair) && (OrderProfit() > MaximizeProfitTreshold) && (CountedOrders < MaxTradingThisPair +1))
          OrderSend(Symbol(), OP_BUY, LotsOptimized(), Ask, 3, Ask - StopLossMaximize * Point * MathPow(10, Digits % 2),
            0, "VOSTOK-MaximizeProfit", MAGICNUMMAX, 0, Green); 
         }
        if ((OrderType() == OP_SELL) && (OrderSymbol() == symbolpair) && (OrderMagicNumber()==MAGICNUMBER || !MAGICNUMMAX) && (AllowMaximize == true) && (MI==0)) { //&& OrdersMaximizeLostToday==0 ) {//&& (TRENDplus==0)) { //&& TREND==0)  {
          if ((OrderSymbol() == symbolpair) && (OrderProfit() > MaximizeProfitTreshold) && (CountedOrders < MaxTradingThisPair +1))
          OrderSend(Symbol(), OP_SELL, LotsOptimized(), Bid, 3, Bid + StopLossMaximize * Point * MathPow(10, Digits % 2),
            0, "VOSTOK-MaximizeProfit", MAGICNUMMAX, 0, Red); 
         }
         }
}


//+------------------------------------------------------------------+
//| Trailing Stop 
//+------------------------------------------------------------------+
void TrailStops()
{        

 for (int j = 0; j < OrdersTotal(); j++) {
         if (OrderSelect(j, SELECT_BY_POS)) {
            if (MAGICNUMBER == OrderMagicNumber()) {
               if (OrderType() == OP_BUY)
                  if (Bid - OrderStopLoss() >= trendTrigger * MyPoint && Bid > OrderStopLoss()) OrderModify(OrderTicket(), 0, Bid - trendStoploss * MyPoint, OrderTakeProfit(), 0, Yellow);
               if (OrderType() == OP_SELL)
                  if (OrderStopLoss() - Ask >= trendTrigger * MyPoint && Ask < OrderStopLoss()) OrderModify(OrderTicket(), 0, Ask + trendStoploss * MyPoint, OrderTakeProfit(), 0, Yellow);
            }
         }
      }

}

